﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace CustomDataGridView
{
    [Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
    public class CustomDataGrdView : DataGridView 
    {
        protected override void OnControlAdded(ControlEventArgs e)
        {
            SubscribeEvents(e.Control);
            base.OnControlAdded(e);
        }

        protected override void OnControlRemoved(ControlEventArgs e)
        {
            UnsubscribeEvents(e.Control);
            base.OnControlRemoved(e);
        }

        protected virtual void SubscribeEvents(Control control)
        {
            control.KeyDown +=new KeyEventHandler(DataColumn_KeyDown);
            control.KeyPress += new KeyPressEventHandler(DataColumn_KeyPress);
            control.ControlAdded += new ControlEventHandler(control_ControlAdded);
            control.ControlRemoved += new ControlEventHandler(control_ControlRemoved);

            foreach (Control innerControl in control.Controls)
            {
                SubscribeEvents(innerControl);
            }
        }

        protected virtual void UnsubscribeEvents(Control control)
        {
            control.KeyDown -= new KeyEventHandler(DataColumn_KeyDown);
            control.KeyPress -= new KeyPressEventHandler(DataColumn_KeyPress);
            control.ControlAdded -= new ControlEventHandler(control_ControlAdded);
            control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved);

            foreach (Control innerControl in control.Controls)
            {
                UnsubscribeEvents(innerControl);
            }
        }

        private void control_ControlAdded(object sender, ControlEventArgs e)
        {
            SubscribeEvents(e.Control);
        }

        private void control_ControlRemoved(object sender, ControlEventArgs e)
        {
            UnsubscribeEvents(e.Control);
        }

        protected virtual void DataColumn_KeyPress(object sender, KeyPressEventArgs e)
        {
            // Apply your logic here whether this is the key pressed event you need.
            // (e.g. "if(SelectedCells != null)")
            //MessageBox.Show(e.KeyChar.ToString());
        }

        protected virtual void DataColumn_KeyDown(object sender, KeyEventArgs e)
        {
 	        
        }

    }


    public class CalendarColumn : DataGridViewColumn
    {
        public CalendarColumn()
            : base(new CalendarCell())
        {
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                // Ensure that the cell used for the template is a CalendarCell. 
                if (value != null &&
                    !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
                {
                    throw new InvalidCastException("Must be a CalendarCell");
                }
                base.CellTemplate = value;
            }
        }
    }

    public class CalendarCell : DataGridViewTextBoxCell
    {

        public CalendarCell()
            : base()
        {
            // Use the short date format. 
            this.Style.Format = "d";
        }

        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            // Set the value of the editing control to the current cell value. 
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            CalendarEditingControl ctl = DataGridView.EditingControl as CalendarEditingControl;
            // Use the default row value when Value property is null. 
            if (this.Value == null)
            {
                ctl.Value = DateTime.Now;//(DateTime)this.DefaultNewRowValue;
            }
            else
            {
                try
                {
                    ctl.Value = (DateTime)this.Value;
                }
                catch
                {
                    ctl.Value = DateTime.Now;
                }
            }
        }

        public override Type EditType
        {
            // Return the type of the editing control that CalendarCell uses.
            get { return typeof(CalendarEditingControl); }
        }

        public override Type ValueType
        {
            // Return the type of the value that CalendarCell contains.
            get {return typeof(DateTime);}
        }

        public override object DefaultNewRowValue
        {
            // Use the current date and time as the default value.
            get { return DateTime.Now; }
        }
    }

    class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
    {
        DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        public CalendarEditingControl()
        {
            this.Format = DateTimePickerFormat.Short;
        }

        // Implements the IDataGridViewEditingControl.EditingControlFormattedValue  
        // property. 
        public object EditingControlFormattedValue
        {
            get { return this.Value.ToShortDateString(); }
            set
            {
                if (value is String)
                {
                    try
                    {
                        // This will throw an exception of the string is  
                        // null, empty, or not in the format of a date. 
                        this.Value = DateTime.Parse((String)value);
                    }
                    catch
                    {
                        // In the case of an exception, just use the  
                        // default value so we're not left with a null 
                        // value. 
                        this.Value = DateTime.Now;
                    }
                }
            }
        }

        // Implements the  
        // IDataGridViewEditingControl.GetEditingControlFormattedValue method. 
        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        { 
            return EditingControlFormattedValue;
        }

        // Implements the  
        // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method. 
        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.Font = dataGridViewCellStyle.Font;
            this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
            this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
        }

        // Implements the IDataGridViewEditingControl.EditingControlRowIndex  
        // property. 
        public int EditingControlRowIndex
        {
            get { return rowIndex;}
            set { rowIndex = value;}
        }

        // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey  
        // method. 
        public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
        {
            // Let the DateTimePicker handle the keys listed. 
            switch (key & Keys.KeyCode)
            {
                case Keys.Left:
                case Keys.Up:
                case Keys.Down:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                case Keys.PageDown:
                case Keys.PageUp:
                    return true;
                default:
                    return !dataGridViewWantsInputKey;
            }
        }

        // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit  
        // method. 
        public void PrepareEditingControlForEdit(bool selectAll)
        {
            // No preparation needs to be done.
        }

        // Implements the IDataGridViewEditingControl 
        // .RepositionEditingControlOnValueChange property. 
        public bool RepositionEditingControlOnValueChange
        {
            get { return false;}
        }

        // Implements the IDataGridViewEditingControl 
        // .EditingControlDataGridView property. 
        public DataGridView EditingControlDataGridView
        {
            get { return dataGridView;}
            set { dataGridView = value;}
        }

        // Implements the IDataGridViewEditingControl 
        // .EditingControlValueChanged property. 
        public bool EditingControlValueChanged
        {
            get { return valueChanged; }
            set { valueChanged = value;}
        }

        // Implements the IDataGridViewEditingControl 
        // .EditingPanelCursor property. 
        public Cursor EditingPanelCursor
        {
            get { return base.Cursor; }
        }

        protected override void OnValueChanged(EventArgs eventargs)
        {   // Notify the DataGridView that the contents of the cell 
            // have changed.
            valueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnValueChanged(eventargs);
        }
    }

    //public class TextBoxAndButtonColumn : DataGridViewColumn
    //{
    //    public TextBoxAndButtonColumn()
    //        : base(new TextAndButtonCell())
    //    {
    //    }

    //    public override DataGridViewCell CellTemplate
    //    {
    //        get
    //        {
    //            return base.CellTemplate;
    //        }
    //        set
    //        {
    //            // Ensure that the cell used for the template is a CalendarCell. 
    //            if (value != null &&
    //                !value.GetType().IsAssignableFrom(typeof(TextAndButtonCell)))
    //            {
    //                throw new InvalidCastException("Must be a TextAndButtonCell");
    //            }
    //            base.CellTemplate = value;
    //        }
    //    }
    //}

    //public class TextAndButtonCell : DataGridViewTextBoxCell
    //{

    //    public TextAndButtonCell()
    //        : base()
    //    {
    //        // Use the short date format. 
    //        //this.Style.Format = "d";
    //    }

    //    public override void InitializeEditingControl(int rowIndex, object
    //        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    //    {
    //        // Set the value of the editing control to the current cell value. 
    //        base.InitializeEditingControl(rowIndex, initialFormattedValue,
    //            dataGridViewCellStyle);
    //        TextAndButtonControl ctl =
    //            DataGridView.EditingControl as TextAndButtonControl;
    //        // Use the default row value when Value property is null. 
    //        if (this.Value == null)
    //        {
    //            ctl.Text = (string)this.DefaultNewRowValue;
    //        }
    //        else
    //        {
    //            ctl.Text = (string)this.Value;
    //        }
    //    }

    //    public override Type EditType
    //    {
    //        get
    //        {
    //            // Return the type of the editing control that CalendarCell uses. 
    //            return typeof(TextAndButtonControl);
    //        }
    //    }

    //    public override Type ValueType
    //    {
    //        get
    //        {
    //            // Return the type of the value that CalendarCell contains. 

    //            return typeof(string);
    //        }
    //    }

    //    public override object DefaultNewRowValue
    //    {
    //        get
    //        {
    //            // Use the current date and time as the default value. 
    //            return "";
    //        }
    //    }
    //}

    //class TextAndButtonControl : UserControl
    //{
    //    private TextBox txtText;
    //    private Button btnButton;

    //    public TextAndButtonControl()
    //    {
    //        this.txtText = new TextBox();
    //        this.Controls.Add(this.txtText);
    //        this.btnButton = new Button();
    //        this.Controls.Add(this.btnButton);
    //        this.renderControl();
    //        this.btnButton.Click += new EventHandler(btnButton_Click);
    //    }

    //    void btnButton_Click(object sender, EventArgs e)
    //    {
    //        MessageBox.Show("Click! The value is:" + this.Text);
    //    }
        
    //    public string Text
    //    {
    //        get { return this.txtText.Text; }
    //        set { this.txtText.Text = value; }
    //    }

    //    public string ButtonText
    //    {
    //        get { return this.btnButton.Text; }
    //        set { this.btnButton.Text = value; }
    //    }

    //    public void renderControl()
    //    {
    //        this.txtText.Location = new  Point(0, 0);
    //        this.txtText.Width = 2 * this.Width / 3;
    //        this.txtText.Height = this.Height;
    //        this.txtText.Location = new Point(2 * this.Width / 3, 0);
    //        this.txtText.Width = this.Width / 3;
    //        this.txtText.Height = this.Height;
    //    }
    //}
}
